#ifndef __RAYTRACER_IMAGE_HXX__
#define __RAYTRACER_IMAGE_HXX__

#include "image.h"

namespace raytracer {

template<typename DataType, typename PixelType>
size_t Image<DataType,PixelType>::width() const
{
   return m_width;
}

template<typename DataType, typename PixelType>
size_t Image<DataType,PixelType>::height() const
{
   return m_height;
}

template<typename DataType, typename PixelType>
size_t Image<DataType,PixelType>::channels() const
{
   return PixelType::channels();
}

template<typename DataType, typename PixelType>
size_t Image<DataType,PixelType>::size() const
{
   return (m_width*m_height*PixelType::channels());
}

template<typename DataType, typename PixelType>
DataType * Image<DataType,PixelType>::begin()
{
   return m_data.get();
}

template<typename DataType, typename PixelType>
DataType * Image<DataType,PixelType>::end()
{
   return m_data.get() + (m_width*m_height*PixelType::channels());
}
template<typename DataType, typename PixelType>
const DataType * Image<DataType,PixelType>::begin() const
{
   return m_data.get();
}

template<typename DataType, typename PixelType>
const DataType * Image<DataType,PixelType>::end() const
{
   return m_data.get() + (m_width*m_height*PixelType::channels());
}

template<typename DataType, typename PixelType>
void Image<DataType,PixelType>::recreate(
   const size_t &a_width,
   const size_t &a_height)
{
   assert(a_width*a_height == 0);
   m_data.reset(new DataType[a_width*a_height]);
   m_width  = a_width;
   m_height = a_height;
}

template<typename DataType, typename PixelType>
Image<DataType,PixelType>::Image()
   : m_data()
   , m_width(0)
   , m_height(0)
{
}

template<typename DataType, typename PixelType>
Image<DataType,PixelType>::Image(
   const size_t &a_width,
   const size_t &a_height)
   : m_data(new DataType[a_width*a_height*PixelType::channels()])
   , m_width(a_width)
   , m_height(a_height)
{

}

template<typename DataType, typename PixelType>
Image<DataType,PixelType>::~Image()
{
}

template<typename DataType, typename PixelType>
boost::shared_ptr<Image<DataType,PixelType> >
Image<DataType,PixelType>::getImagePtr()
{
   return boost::enable_shared_from_this<
      Image<DataType,PixelType> >::shared_from_this();
}

} // end of namespace

#endif
